Conditional statements

The most common conditional statement in Python is the if-elif-else statement:

if variable > 5:
  do_something()
elif variable > 0:
  do_something_else()
else:
  give_up()

Compared to languages like C, Java or Lisp, do you feel something is missing?

Python is whitespace-aware and it uses the so-called off-side rule to annotate code blocks. This has several benefits

  • It's easy to read at a glance
  • levels of indentation are processed pre-attentively to conserve brain power for everything
  • It's easy to write without having to worry too much

One corollary of the indentation is that you need to be very aware of when you're using the tabulator character and when you're using a space. Most Python programmers only use whitespace and configure their editor to output several spaces when tab is pressed.

Note: the line before a deeper level of indentation ends in a colon ":". This syntax is part of beginning a new code block and surprisingly easy to forget.


In [ ]:
value = 4
value = value + 1
if value < 5:
    print("value is less than 5")
elif value > 5:
    print("value is more than 5")
else:
    print("value is precisely 5")
# go ahead and experiment by changing the value

There is no switch-case type of statement in Python.

Note: When evaluating conditional statements the values 0, an empty string and an empty list all evaluate to False. This can be confusing as it is one of the few places where Python doesn't enforce strong typing.


In [ ]:
list_ = [1]
list_.pop()
if not list_:
    print("list is None or empty")

While statement

Python supports while statement familiar from many languages. It is not nearly as much used because of iterators (covered later).

value = 5
while value > 0:
  value = do_something(value)

The following example shows how a list is used as the conditional.


In [ ]:
list_ = [1, 2, 3, 4]
while list_: # remember, an empty list evaluates as False for conditional purposes
    print(list_.pop()) # pop() removes the last entry from the list

Iterating

Python has a for-loop statement that is similar to the foreach statement in a lot of other languages.

It is possible to loop over any iterables, i.e. lists, sets, tuples, even dicts.


In [ ]:
synonyms = ["is dead", "has kicked the bucket", "is no more", "ceased to be"]
for phrase in synonyms:
    print("This parrot " + phrase + ".")

It is possible to unpack things in this stage if that is required.


In [ ]:
pairs = (
        (1, 2),
        [3, 4],
        (5, 6),
)

for x, y in pairs:
    print("A is " + str(x))
    print("B is " + str(y))

In dictionaries the keys are iterated over by default.


In [ ]:
airspeed_swallows = {"African": 20, "European": 30}
for swallow in airspeed_swallows:
    print("The air speed of " + swallow + " swallows is "+ str(airspeed_swallows[swallow]))

It is still possible to loop through numbers using the built-in range function that returns an iterable with numbers in sequence.


In [ ]:
for i in range(5):
    print(str(i))

In [ ]:
# The function supports arbitary step lengths and going backwards

for i in range(99, 90, -2): # parameters are from, to and step length in that order
    print(str(i) +" boxes of bottles of beer on the wall")

The function enumerate returns the values it's given with their number in the collection.


In [ ]:
my_list = ["a", "b", "c", "d", "e"]
for index, string in enumerate(my_list):
    print(string +" is the alphabet number "+ str(index))

Breaking and continuing

Sometimes it is necessary to stop the execution of a loop before it's time. For that there is the break keyword.

At other times it is desired to end that particular step in the loop and immediately move to the next one.

Both of the keywords could be substituted with complex if-else statements but a well-considered break or continue statement is more readable to the next programmer.


In [ ]:
for i in range(20):
    if i % 7 == 6: # modulo operator
        break #
    print(i)

In [ ]:
for i in range(-5, 5, 1):
  if i == 0:
        print ("not dividing by 0")
        continue
  print("5/" + str(i) + " equals " + str(5/i))

List comprehension

The act of modifying all the values in a list into a new list is so common in programming that there is a special syntax for it in python, the list comprehension.


In [ ]:
list_ = [value*3-1 for value in range(5)]
list_

It is not necessary to use list comprehensions but they are mentioned so they can be understood if discovered in other programs.

Part of the Zen of Python says

There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.

List comprehensions are the one and obvious way to do these kinds of operations so they are presented even though they may be considered "advanced" syntax.

There is also possibility to add a simple test to the statement.


In [ ]:
list_2 = [value*3-1 for value in range(10) if value % 2 == 0] #only take even numbers
list_2

Note: List comprehensions always create the entire list in memory. When handling large amounts of data or in an environment with limited memory it's often a good idea to avoid creating large data structures in memory.

In Python a language feature called generators helps you do this. There is extra material about this in another notebook.

Exercises

See under ../exercises/